package cn.edu.tsinghua.training.cms.demo.action;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;

import cn.edu.tsinghua.training.cms.demo.entity.Admin;
import cn.edu.tsinghua.training.cms.demo.entity.Article;
import cn.edu.tsinghua.training.cms.demo.entity.Channel;
import cn.edu.tsinghua.training.cms.demo.service.AdminService;
import cn.edu.tsinghua.training.cms.demo.service.ArticleService;
import cn.edu.tsinghua.training.cms.demo.service.ChannelService;
import cn.edu.tsinghua.training.cms.demo.util.Constants;
import freemarker.template.Template;

@Results({
	@Result(name="register_success", location="/index.jsp", type="redirect"),
	@Result(name="login_success", location="/admin/index.jsp", type="redirect"),
	@Result(name="login_input", location="/admin/login.jsp"),
	@Result(name="logout_success", location="/index.jsp", type="redirect"),
	@Result(name="staticize_success", location="/admin/index.jsp", type="redirect")
})
public class AdminAction extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Admin admin;
	@Autowired
	private AdminService adminService;
	@Autowired
	private ChannelService channelService;
	@Autowired
	private ArticleService articleService;
	@Autowired
	private FreeMarkerConfig freeMarkerConfig;

	@Action("admin_add")
	public String add() throws Exception {
		admin.setPassword(DigestUtils.md5DigestAsHex(admin.getPassword().getBytes()));
		adminService.add(admin);
		return "register_success";
	}

	@Action("admin_login")
	public String login() throws Exception {
		Admin admin = adminService.login(this.admin);
		if (admin != null) {
			getSession().put("admin", admin);
			return "login_success";
		} else {
			getRequest().put("message", "Error.");
			return "login_input";
		}
	}

	@Action("admin_logout")
	public String logout() throws Exception {
		getSession().clear();
		return "logout_success";
	}
	
	@Action("staticize")
	public String staticize() throws Exception {
		
		staticizeIndex();
		
		List<Channel> channels = channelService.list();
		for (Channel channel : channels) {
			staticizeChannels(channel.getId());
		}
		
		List<Article> articles = articleService.queryAll();
		for (Article article : articles) {
			staticizeArticles(article.getId());
		}
		
		return "staticize_success";
	}
	
	private void staticizeIndex() throws Exception {
		String hql = "select distinct c from Channel c left outer join fetch c.articles";//WEB lazy懒  延迟加载
		List<Channel> channels = channelService.query(hql, null, null);
		for (Channel channel : channels) {
			System.out.println("--->" + channel.getTitle());
			Set<Article> articles = channel.getArticles();
			for (Article article : articles) {
				System.out.println(article.getTitle());
			}
		}
		Template template = freeMarkerConfig.getConfiguration().getTemplate("html/index.html");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("channels", channels);
		File file = new File(Constants.PATH + "index.html");
		Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
		template.process(map, writer);
		writer.close();
	}
	
	private void staticizeChannels(long channelid) throws Exception {
		String hql = "from Channel c left outer join fetch c.articles where c.id=:channelid";
		String[] paramNames = {"channelid"};
		Object[] values = {channelid};
		Channel channel = channelService.query(hql, paramNames, values).get(0);
		Template template = freeMarkerConfig.getConfiguration().getTemplate("html/channel.html");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("channel", channel);
		File path = new File(Constants.PATH + channel.getDirectory());
		if (!path.exists()) {
			path.mkdir();
		}
		File file = new File(Constants.PATH + channel.getDirectory() + "/" +"index.html");
		Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
		template.process(map, writer);
		writer.close();
	}
	
	private void staticizeArticles(long articleid) throws Exception {
		String hql = "from Article a where a.id=:articleid";
		String[] paramNames = {"articleid"};
		Object[] values = {articleid};
		Article article = articleService.query(hql, paramNames, values).get(0);
		Template template = freeMarkerConfig.getConfiguration().getTemplate("html/article.html");
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("article", article);
		File path = new File(Constants.PATH + article.getChannel().getDirectory());
		if (!path.exists()) {
			path.mkdir();
		}
		File file = new File(Constants.PATH + article.getChannel().getDirectory() + "/" + article.getTitle() + ".html");
		Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
		template.process(map, writer);
		writer.close();
	}

	public Admin getAdmin() {
		return admin;
	}

	public void setAdmin(Admin admin) {
		this.admin = admin;
	}

}
